using AutoMapper;
using MediatR;
using System;
using System.Threading;
using System.Threading.Tasks;
using Work.API.Applications.Write.Commands;
using Work.Domain.DrugManage;
using Work.ErrorCode;
using Work.Infrastructure.Interfaces;

namespace Work.API.Applications.Write.CommandHandlers
{
    /// <summary>
    /// 药品入库处理器（用于药品入库模块 - 再次入库）
    /// 业务逻辑：
    /// 1. 验证药品是否存在
    /// 2. 创建入库记录
    /// 3. 更新药品库存数量
    /// </summary>
    public class InboundDrugCommandHandler : IRequestHandler<InboundDrugCommand, ApiResult<int>>
    {
        private readonly IBaseRepository<Drug> _drugRepo;
        private readonly IBaseRepository<DrugInbound> _inboundRepo;
        private readonly IMapper _mapper;

        public InboundDrugCommandHandler(
            IBaseRepository<Drug> drugRepo,
            IBaseRepository<DrugInbound> inboundRepo,
            IMapper mapper)
        {
            _drugRepo = drugRepo;
            _inboundRepo = inboundRepo;
            _mapper = mapper;
        }

        public async Task<ApiResult<int>> Handle(InboundDrugCommand request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<int>();

            try
            {
                // 1. 验证药品是否存在
                var drug = await _drugRepo.GetById(request.DrugId);
                if (drug == null || !drug.IsEnabled)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = "药品不存在或已禁用";
                    result.Data = 0;
                    return result;
                }

                // 2. 检查入库后库存是否超过库存上限
                int newInventory = drug.Inventory + request.Quantity;
                if (newInventory > drug.InventoryUpperLimit)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = $"入库后库存（{newInventory}）将超过库存上限（{drug.InventoryUpperLimit}），不能入库。当前库存：{drug.Inventory}，入库数量：{request.Quantity}，最大允许入库数量：{drug.InventoryUpperLimit - drug.Inventory}。请调整入库数量。";
                    result.Data = 0;
                    return result;
                }

                // 3. 检查入库后库存是否低于库存下限（可选检查，如果允许低于下限也可以入库）
                // 这里不阻止入库，因为入库的目的是增加库存，即使低于下限也可以入库
                // 但可以给出警告提示（如果需要的话）

                // 4. 创建入库记录
                var inbound = new DrugInbound
                {
                    DrugId = request.DrugId,
                    Quantity = request.Quantity,
                    UnitPrice = request.UnitPrice,
                    TotalAmount = request.UnitPrice * request.Quantity,
                    ProductionDate = request.ProductionDate,
                    ExpirationDate = request.ExpirationDate,
                    BatchNumber = request.BatchNumber,
                    Supplier = request.Supplier,
                    InboundDate = DateTime.Now,
                    Operator = request.Operator,
                    Remarks = request.Remarks,
                    CreateTime = DateTime.Now
                };

                var inboundRows = await _inboundRepo.AddAsync(inbound);

                if (inboundRows <= 0)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = "入库记录创建失败";
                    result.Data = 0;
                    return result;
                }

                // 5. 更新药品库存数量
                drug.Inventory += request.Quantity;
                drug.UpdateTime = DateTime.Now;
                drug.UpdateBy = request.Operator;

                var drugRows = await _drugRepo.UpdateAsync(drug);

                if (drugRows > 0)
                {
                    result.Code = ApiEnum.成功;
                    result.Message = "药品入库成功";
                    result.Data = inbound.InboundId;
                }
                else
                {
                    result.Code = ApiEnum.失败;
                    result.Message = "入库记录创建成功，但库存更新失败";
                    result.Data = inbound.InboundId;
                }
            }
            catch (Exception ex)
            {
                result.Code = ApiEnum.失败;
                result.Message = $"入库失败：{ex.Message}";
                result.Data = 0;
            }

            return result;
        }
    }
}

